﻿using System;
using System.Collections.Generic;
using System.Linq;
using CommonControlLibrary.Common;
using DBAccessLibrary.Model;
using System.Collections.ObjectModel;
using System.Windows.Media;
using DBAccessLibrary.Common;
using QueryResource.Common;
using System.Threading;
using System.Windows;
using DBAccessLibrary;
using System.Data;
using System.Threading.Tasks;

namespace QueryResource.ViewModel
{
    public class DataComparsionViewModel
    {
        public DataComparsionViewModel()
        {
            DataSourceList = new ObservableCollection<DBComparsionEntity>();
            TargetSourceList = new ObservableCollection<DBComparsionEntity>();
            TableComparisonList = new List<TableComparisonEntity>();
            ColumnComparisonList = new List<ColumnComparisonEntity>();
        }
        //查询结果
        private DbEntityCache DataSource { get; set; }
        private DbEntityCache TargetSource { get; set; }
        //连接字符串
        private ConnectionModel DataConnection { get; set; }
        private ConnectionModel TargetConnection { get; set; }
        //树 
        public ObservableCollection<DBComparsionEntity> DataSourceList { get; set; }
        public ObservableCollection<DBComparsionEntity> TargetSourceList { get; set; }
        //列对比
        public List<ColumnComparisonEntity> ColumnComparisonList { get; set; }
        //表对比
        public List<TableComparisonEntity> TableComparisonList { get; set; }
        private void ConvertDBComparsionEntity(DbEntityCache dbinfo, ObservableCollection<DBComparsionEntity> source)
        {
            if (dbinfo != null)
            {
                this.ViewInvoke(source.Clear);
                foreach(TableEntity table in dbinfo.TableList)
                {
                    DBComparsionEntity entity = new DBComparsionEntity {Name = table.Name};

                    this.ViewInvoke(() => source.Add(entity));
                    DispatcherHelper.DoEvents();
                }
            }
        }
        /// <summary>
        /// 连接
        /// </summary>
        /// <param name="source"></param>
        /// <param name="target"></param>
        /// <param name="action"></param>
        public void Connect(ConnectionModel source, ConnectionModel target, Action action)
        {
            Exec(() =>
            {
                DataConnection = source;
                DataSource = DBOperatorFactory.GetOperator.GetDbInfos(source,WriteLog);
                ConvertDBComparsionEntity(DataSource, DataSourceList);

                DispatcherHelper.DoEvents();

                TargetConnection = target;
                TargetSource = DBOperatorFactory.GetOperator.GetDbInfos(target, WriteLog);
                ConvertDBComparsionEntity(TargetSource, TargetSourceList);
                if (action != null)
                    action();
            }, "加载数据源");
        }
        /// <summary>
        /// 导入数据
        /// </summary>
        /// <param name="isDeleteAll"></param>
        public void ExportData(bool isDeleteAll)
        {
            if (DataSource == null || TargetSource == null)
            {
                return;
            }

            Exec(() =>
            {
                foreach (DBComparsionEntity entity in TargetSourceList)
                {
                    Export(entity, isDeleteAll);
                }
            }, "数据导入");
        }
        /// <summary>
        /// 行数对比
        /// </summary>
        public void SyncRowCount()
        {
            if (DataSource == null || TargetSource == null)
            {
                return;
            }
            Exec(() =>
            {

                foreach (TableEntity entity in DataSource.TableList)
                {
                    TableEntity entity1 = entity;
                    DBComparsionEntity sourceEntity = DataSourceList.FirstOrDefault(o => o.Name.ToUpper() == entity1.Name.ToUpper());
                    try
                    {
                        DBComparsionEntity targetEntity = TargetSourceList.FirstOrDefault(o => o.Name.ToUpper() == entity1.Name.ToUpper());

                        if (sourceEntity != null)
                        {
                            sourceEntity.IsSelected = true;

                            if (targetEntity == null)
                            {
                                sourceEntity.FontColor = Brushes.Red;
                                continue;
                            }
                        }
                        if (targetEntity != null) targetEntity.IsSelected = true;
                        string selectsql = "select count(*) from [" + entity.Name+"]";
                        int count1 = Convert.ToInt32(DBOperatorFactory.GetOperator.ExecScalar(selectsql, DataConnection));
                        int count2 = Convert.ToInt32(DBOperatorFactory.GetOperator.ExecScalar(selectsql, TargetConnection));

                        if (count1 >= count2)
                        {
                            ViewInvoke(() =>
                            {
                                DataSourceList.Remove(sourceEntity);
                                TargetSourceList.Remove(targetEntity);
                            });
                        }
                        else
                        {
                            if (sourceEntity != null)
                            {
                                sourceEntity.FontColor = Brushes.Blue;
                                sourceEntity.Name = sourceEntity.Name + "[" + count1 + "]";
                            }

                            if (targetEntity != null)
                            {
                                targetEntity.FontColor = Brushes.Blue;
                                targetEntity.Name = targetEntity.Name + "[" + count2 + "]";
                            }
                        }

                        DispatcherHelper.DoEvents();
                    }
                    catch (Exception ex)
                    {
                        WriteLog(entity.Name + "出错了.详细:" + ex.Message, Colors.Red);
                        if (sourceEntity != null) 
                            sourceEntity.FontColor = Brushes.Gray;
                        DispatcherHelper.DoEvents();
                    }
                }
            }, "行数对比");
        }
        /// <summary>
        /// 对比数据
        /// </summary>
        public void SyncData()
        {
            Exec(() => {
                foreach (TableComparisonEntity entity in TableComparisonList.Where(o => o.IsUpdate))
                {
                    if (string.IsNullOrEmpty(entity.UpdateContent))
                    {
                        TableComparisonEntity entity1 = entity;
                        foreach (ColumnComparisonEntity column in ColumnComparisonList.Where(o => o.TableName.ToUpper() == entity1.TableName.ToUpper() && !string.IsNullOrEmpty(o.UpdateContent)))
                        {
                            try
                            {
                                if (!column.IsUpdate)
                                    continue;
                                WriteLog(column.UpdateContent, Colors.Blue);
                                DBOperatorFactory.GetOperator.ExecSql(column.UpdateContent, DataConnection);
                            }
                            catch (Exception ex)
                            {
                                WriteLog("出错了," + entity.TableName + "->" + ex.Message, Colors.Red);
                            }
                        }
                    }
                    else
                    {
                        try
                        {
                            WriteLog(entity.UpdateContent, Colors.Blue);
                            DBOperatorFactory.GetOperator.ExecSql(entity.UpdateContent, DataConnection);
                        }
                        catch (Exception ex)
                        {
                            WriteLog("出错了," + entity.TableName + "->" + ex.Message, Colors.Red);
                        }
                    }
                }
            }, "更新数据");
          
        }
        /// <summary>
        /// 移除相同表
        /// </summary>
        public void RemoveData()
        {
            if (TargetSourceList == null)
                return;
            Exec(() =>
            {
                foreach (DBComparsionEntity entity in TargetSourceList)
                {
                    string dropsql = "drop table [" + entity.Name+"]";
                    try
                    {
                        DBComparsionEntity entity1 = entity;
                        DBComparsionEntity dataEntity = DataSourceList.FirstOrDefault(o => o.Name.ToUpper() == entity1.Name.ToUpper());
                        if (dataEntity != null)
                        {
                            DBOperatorFactory.GetOperator.ExecSql(dropsql, DataConnection);
                            this.ViewInvoke(() => DataSourceList.Remove(dataEntity));
                        }
                    }
                    catch (Exception ex)
                    {
                        entity.SqlContent = dropsql;
                        WriteLog("出错了," + entity.Name + "->" + ex.Message, Colors.Red);
                    }

                    DispatcherHelper.DoEvents();
                }
            }, "移除相同表");
        }
        /// <summary>
        /// 部分对比
        /// </summary>
        /// <param name="entity"></param>
        /// <param name="isDeleteAll"></param>
        public void PartExport(DBComparsionEntity entity, bool isDeleteAll)
        {
            if (DataSource == null || TargetSource == null)
            {
                return;
            }
           
            if (entity != null)
            {
                DBComparsionEntity targetEntity = TargetSourceList.FirstOrDefault(o => o.Name == entity.Name);
                if (targetEntity != null)
                {
                    Exec(() => Export(targetEntity, isDeleteAll), "数据导入");
                }
            }

        }
        /// <summary>
        /// 数据类别对比
        /// </summary>
        /// <param name="action"></param>
        public void Comparsion(Action<List<TableComparisonEntity>> action)
        {
            Exec(() =>
            {
                TableComparisonList.Clear();
                ColumnComparisonList.Clear();
                DBComparsionEntity[] copySource = new DBComparsionEntity[DataSourceList.Count];
                DataSourceList.CopyTo(copySource, 0);
                foreach (TableEntity source in DataSource.TableList)
                {
                    #region 逻辑

                    TableEntity source1 = source;
                    DBComparsionEntity sourceNode = DataSourceList.FirstOrDefault(o => o.Name.ToUpper() == source1.Name.ToUpper());
                    TableEntity targetNode = TargetSource.TableList.FirstOrDefault(o => o.Name.ToUpper() == source1.Name.ToUpper());
                    if (targetNode == null)
                    {
                        //如果不存在表  则显示红色
                        if (sourceNode != null) sourceNode.FontColor = Brushes.Red;
                        continue;
                    }
                    TableComparisonEntity tc = new TableComparisonEntity {TableName = source.Name};

                    foreach (FieldEntity sourceColumn in source.FileNodes)
                    {
                        Filter(source, targetNode, sourceColumn, tc);
                    }
                    
                    //判断 目标数据中存在的列 而 源数据中不存在的列
                    foreach (FieldEntity targetColumn in targetNode.FileNodes)
                    {
                        FieldEntity column1 = targetColumn;
                        FieldEntity column = source.FileNodes.FirstOrDefault(p => p.Name.ToUpper() == column1.Name.ToUpper());

                        if (column == null)
                        {
                            ColumnComparisonEntity sourceColumnComparsion = new ColumnComparisonEntity
                           {
                               TableName = targetNode.Name,
                               ColumnName = targetColumn.Name,
                               Status = ComparisonType.缺失,
                               SourceType = "Source"
                           };
                            ColumnComparisonEntity targetColumnComparsion = new ColumnComparisonEntity
                            {
                                TableName = targetNode.Name,
                                ColumnName = targetColumn.Name,
                                DataType = targetColumn.TypeName,
                                IsNullable = targetColumn.IsNull ? "Null":"Not Null",
                                IsPrimaryKey = targetColumn.IsPrimaryKey,
                                Length = targetColumn.Length,
                                Status = ComparisonType.缺失,
                                SourceType = "Target"
                            };

                            try
                            {

                               
                                string addColumn =
                                   DBOperatorFactory.GetGrammar(DataConnection).AddColumn(targetColumn);

                                sourceColumnComparsion.UpdateContent = addColumn;

                                ColumnComparisonList.Add(sourceColumnComparsion);
                                ColumnComparisonList.Add(targetColumnComparsion);
                            }
                            catch (Exception ex)
                            {
                                MessageBox.Show(ex.Message);
                            }
                        }
                        DispatcherHelper.DoEvents();
                    }
                    if (tc.TableStatus != ComparisonType.相等)
                    {
                        tc.UpdateCount = ColumnComparisonList.Count(o => o.TableName.ToUpper() == source1.Name.ToUpper() && o.SourceType == "Source" && o.Status != ComparisonType.相等);
                        TableComparisonList.Add(tc);
                    }
                    #endregion
                }

                //判断 目标数据中存在的表 而 源数据中不存在的表
                foreach (TableEntity target in TargetSource.TableList)
                {
                    TableEntity target1 = target;
                    DBComparsionEntity sourceNode = copySource.FirstOrDefault(o => o.Name.ToUpper() == target1.Name.ToUpper());
                    DBComparsionEntity targetNode = TargetSourceList.FirstOrDefault(o => o.Name.ToUpper() == target1.Name.ToUpper());
                    if (sourceNode == null)
                    {
                        //如果不存在表  则显示红色
                        if (targetNode != null)
                        {
                            targetNode.FontColor = Brushes.Red;

                            TableComparisonList.Add(new TableComparisonEntity
                                                        {
                                                            TableName = targetNode.Name,
                                                            TableStatus = ComparisonType.缺失,
                                                            IsUpdate = false,
                                                            UpdateContent = DBOperatorFactory.GetGrammar(this.DataConnection).GetCreateInfo(this.DataConnection.ConnectType,target)
                                                        });

                            foreach (FieldEntity field in target.FileNodes)
                            {
                                ColumnComparisonList.Add(new ColumnComparisonEntity
                                                             {
                                                                 TableName = targetNode.Name,
                                                                 ColumnName = field.Name,
                                                                 SourceType = "Source"
                                                             });
                                ColumnComparisonList.Add(new ColumnComparisonEntity
                                                             {
                                                                 TableName = targetNode.Name,
                                                                 ColumnName = field.Name,
                                                                 Length = field.Length,
                                                                 DataType = field.TypeName,
                                                                 IsNullable = field.IsNull ? "Null":"Not Null",
                                                                 IsPrimaryKey = field.IsPrimaryKey,
                                                                 SourceType = "Target"
                                                             });
                            }
                        }
                        continue;
                    }
                    DispatcherHelper.DoEvents();
                }
                if (action != null)
                {
                    action(TableComparisonList);
                }
            }, "数据对比");
        }
        /// <summary>
        /// 刷新
        /// </summary>
        /// <param name="action"></param>
        public void Refresh(Action action = null)
        {
            Action refaction = () =>
            {
                DataSource = DBOperatorFactory.GetOperator.GetDbInfos(DataConnection,WriteLog);
                ConvertDBComparsionEntity(DataSource, DataSourceList);

                TargetSource = DBOperatorFactory.GetOperator.GetDbInfos(TargetConnection,WriteLog);
                ConvertDBComparsionEntity(TargetSource, TargetSourceList);
            };
            Task.Factory.FromAsync(refaction.BeginInvoke, refaction.EndInvoke, null)
                .ContinueWith(t => {
                    if (action != null)
                    {
                        Thread.Sleep(500);
                        action();
                    }
                    IsBusy = false;
                });
        }
        /// <summary>
        /// 过滤 用于 对比功能
        /// </summary>
        /// <param name="sourceEntity"></param>
        /// <param name="targetEntity"></param>
        /// <param name="sourceColumn"></param>
        /// <param name="tc"></param>
        public void Filter(TableEntity sourceEntity, TableEntity targetEntity, FieldEntity sourceColumn, TableComparisonEntity tc)
        {
            FieldEntity targetColumn = targetEntity.FileNodes.FirstOrDefault(p => p.Name.ToUpper() == sourceColumn.Name.ToUpper());
            bool isadd = false;
            ColumnComparisonEntity sourceColumnComparsion = new ColumnComparisonEntity
            {
                TableName = sourceEntity.Name,
                ColumnName = sourceColumn.Name,
                DataType = sourceColumn.TypeName,
                IsNullable = sourceColumn.IsNull ? "Null" : "Not Null",
                IsPrimaryKey = sourceColumn.IsPrimaryKey,
                SourceType = "Source",
                Length = sourceColumn.Length
            };
            ColumnComparisonEntity targetColumnComparsion = new ColumnComparisonEntity
            {
                TableName = targetEntity.Name,
                ColumnName = sourceColumn.Name,
                SourceType = "Target"
            };
            if (targetColumn == null)
            {
                //如果目标源 不存在列 
                sourceColumnComparsion.Status = ComparisonType.缺失;
                targetColumnComparsion.Status = ComparisonType.缺失;
                isadd = true;
            }
            else
            {
                targetColumnComparsion.DataType = targetColumn.TypeName;
                targetColumnComparsion.IsNullable = targetColumn.IsNull ? "Null":"Not Null";
                targetColumnComparsion.IsPrimaryKey = targetColumn.IsPrimaryKey;
                targetColumnComparsion.Length = targetColumn.Length;
                #region 判断
                //1.判断可空属性，当源为 可空 而目标为 不可空时  才视为不等于
                if (sourceColumn.IsNull && !targetColumn.IsNull)
                {
                    sourceColumnComparsion.Status = ComparisonType.不等于;
                    targetColumnComparsion.Status = ComparisonType.不等于;
                    sourceColumnComparsion.ComparisionInfo |= ColumnComparisonInfo.可空类型不相等;
                    isadd = true;
                    string sql = string.Empty;
                   
                    sourceColumnComparsion.UpdateContent = string.Format(sql,
                                       sourceEntity.Name,
                                       sourceColumn.Name,
                                       sourceColumn.TypeName,
                                       string.IsNullOrEmpty(sourceColumn.Length) && sourceColumn.Length != "0" ? "(" + sourceColumn.Length + ")" : "",
                                       targetColumn.IsNull);
                }
                //2:判断长度 当源的长度 小于 目标源的长度时 才视为不等于
                if (sourceColumn.Length != targetColumn.Length)
                {
                    int slength, tlength;
                    int.TryParse(sourceColumn.Length, out slength);
                    int.TryParse(targetColumn.Length, out tlength);
                    if (slength >= tlength)
                    { }
                    else
                    {
                        sourceColumnComparsion.Status = ComparisonType.不等于;
                        targetColumnComparsion.Status = ComparisonType.不等于;
                        sourceColumnComparsion.ComparisionInfo |= ColumnComparisonInfo.长度不相等;
                        isadd = true;
                        sourceColumnComparsion.UpdateContent = string.Join(";"+Environment.NewLine,DBOperatorFactory.GetGrammar(DataConnection).EditColumn(sourceColumn));
                    }
                }
                //3.判断主键
                if ((sourceColumn.IsPrimaryKey && !targetColumn.IsPrimaryKey) || (!sourceColumn.IsPrimaryKey && targetColumn.IsPrimaryKey))
                {
                    sourceColumnComparsion.Status = ComparisonType.不等于;
                    targetColumnComparsion.Status = ComparisonType.不等于;
                    sourceColumnComparsion.ComparisionInfo |= ColumnComparisonInfo.主键不相等;
                    isadd = true;
                }
                //4.判断类型
                if (sourceColumn.TypeName != targetColumn.TypeName)
                {
                    if (sourceColumn.TypeName == "VARCHAR" && targetColumn.TypeName == "VARCHAR2")
                    { }
                    else if ((sourceColumn.TypeName == "INTEGER" || targetColumn.TypeName == "DECIMAL") && targetColumn.TypeName == "NUMBER")
                    { }
                    else if (sourceColumn.TypeName == "TIMESTAMP" && targetColumn.TypeName == "DATE")
                    { }
                    else if (sourceColumn.TypeName == "TIMESTAMP" && targetColumn.TypeName == "TIMESTAMP(6)")
                    { }
                    else
                    {
                        sourceColumnComparsion.Status = ComparisonType.不等于;
                        targetColumnComparsion.Status = ComparisonType.不等于;
                        sourceColumnComparsion.ComparisionInfo |= ColumnComparisonInfo.数据类型不相等;
                        isadd = true;
                    }
                }
                #endregion
            }
            if (isadd)
            {
                tc.TableStatus = ComparisonType.不等于;
                ColumnComparisonList.Add(sourceColumnComparsion);
                ColumnComparisonList.Add(targetColumnComparsion);
            }


            DispatcherHelper.DoEvents();
        }
        /// <summary>
        /// 导入数据
        /// </summary>
        /// <param name="targetEntity"></param>
        /// <param name="isDeleteAll"></param>
        private void Export(DBComparsionEntity targetEntity, bool isDeleteAll)
        {
            DBComparsionEntity sourceEntity = DataSourceList.FirstOrDefault(o => o.Name.ToUpper() == targetEntity.Name.ToUpper());
            if (sourceEntity == null)
                return;
            try
            {
                if (isDeleteAll)
                {
                    string deleteSql = "delete from  [" + sourceEntity.Name+"]";
                    DBOperatorFactory.GetOperator.ExecSql(deleteSql, DataConnection);
                   
                }
                
                    string sql = @"select * from [" + sourceEntity.Name+"]";
                    DataSet ds = DBOperatorFactory.GetOperator.ExecSqlToDS(sql, TargetConnection);
                   DataTable dt = ds.Tables[0];
               

                if (dt.Rows.Count == 0)
                {
                    sourceEntity.FontColor = Brushes.Blue;
                    sourceEntity.Description = "[0]";
                    return;
                }
                sourceEntity.IsSelected = true;
                targetEntity.IsSelected = true;
                TableEntity source = DataSource.TableList.FirstOrDefault(o => o.Name == sourceEntity.Name);
                if (source != null)
                {
                    string[] columns = source.FileNodes.Select(o => o.Name).ToArray(); 
              
                    int count = dt.Rows.Count;
                    string columnArray = string.Join(",", columns);
                    string paramArray = "@" + string.Join(",@", columns);
                    WriteLog("开始导出表" + sourceEntity.Name + ",行数:" + count, Colors.Blue);
                    for (int i = 0; i < count; i++)
                    {
                        DataRow row = dt.Rows[i];
                        string insertsql = string.Format("insert into [{0}]({1}) values({2})", sourceEntity.Name, columnArray, paramArray);

                        List<DBParam> paramlist = source.FileNodes.Select(field => CreateParam(field, row[field.Name])).ToList();

                        DBOperatorFactory.GetOperator.ExecSql(insertsql, DataConnection, paramlist);
                   
                        sourceEntity.Description = "(" + i * 100 / count + "%)";
                    }

                    sourceEntity.FontColor = Brushes.Green;
                    sourceEntity.Description = "[" + count + "]";
                }
            }
            catch (Exception e)
            {
                sourceEntity.FontColor = Brushes.Red;
                WriteLog("出错了." + sourceEntity.Name + "-->" + e.Message, Colors.Red);
            }
        }
        /// <summary>
        /// 用于 不同数据库中 增加类型的匹配
        /// </summary>
        /// <param name="field"></param>
        /// <param name="value"></param>
        /// <returns></returns>
        private DBParam CreateParam(FieldEntity field,object value)
        {
            DBParam param = new DBParam
                                {
                                    Name = field.TransName, 
                                    Value = value
                                };
            if (field.TypeName == "CLOB")
            {
                if (DataConnection.ConnectType == DBType.DB2 || DataConnection.ConnectType == DBType.Oracle)
                {
                    param.TypeName = "CLOB";
                }
            }
            else if (field.TypeName == "BLOB")
            {
                if (DataConnection.ConnectType == DBType.DB2)
                {
                    param.TypeName = "BINARY";
                }
                else if (DataConnection.ConnectType == DBType.Oracle)
                {
                    param.TypeName = "BLOB";
                }
            }
            return param;
        }
       
        /// <summary>
        /// 根据表名获取源数据的列信息
        /// </summary>
        /// <param name="tabName"></param>
        /// <returns></returns>
        public List<FieldEntity> GetFieldList(string tabName)
        {
            if (DataSource != null)
            {
                TableEntity entity = DataSource.TableList.FirstOrDefault(o => o.Name == tabName);
                if (entity != null)
                    return entity.FileNodes.ToList();
            }
            return null;
        }

        /// <summary>
        /// 获取2个数据源中 相应的表数据
        /// </summary>
        /// <param name="tablename"> </param>
        /// <param name="action"></param>
        public void GetTableRowsInfo(string tablename,Action<string,DataSet> action)
        {
            
            Action taskAction = () =>
            {
                string selectSql = string.Format("select * from [{0}]", tablename);
                DataSet sourceDS = DBOperatorFactory.GetOperator.ExecSqlToDS(selectSql, DataConnection);
                action("SOURCE", sourceDS);

                DataSet targetDS = DBOperatorFactory.GetOperator.ExecSqlToDS(selectSql, TargetConnection);
                action("TARGET", targetDS);
              
            };
            Task.Factory.StartNew(taskAction);
        }

        /// <summary>
        /// 通过表名 进行从目标到源 导入数据 
        /// 有则更新没有则插入
        /// </summary>
        /// <param name="tablename"></param>
        /// <param name="dt"> </param>
        /// <param name="dic"> </param>
        /// <param name="showmessag"> </param>
        public void TableRowsExport(string tablename,DataTable dt,Dictionary<string,string> dic,Func<bool> showmessag)
        {
            TableEntity targetEntity = TargetSource.TableList.FirstOrDefault(o => o.Name == tablename);
            TableEntity sourceEntity = DataSource.TableList.FirstOrDefault(o => o.Name == tablename);
            if (targetEntity != null)
            {
                try
                {
                    string columnArray = string.Empty;
                    string paramArray = string.Empty;
                    string where =string.Empty;
                    string set =string.Empty;
                    foreach (DataRow row in dt.Rows)
                    {
                        if (sourceEntity != null)
                        {
                            DataRow row1 = row;
                            List<DBParam> paramlist = (from field in sourceEntity.FileNodes 
                                                       let value = GetStrateGy(field.TransName, dic, row1[field.TransName]) 
                                                       where value != null 
                                                       select CreateParam(field, value)).ToList();


                            if (columnArray == string.Empty)
                            {
                                var columnList = paramlist.Select(o => o.Name);
                                columnArray = string.Join(",", columnList.ToArray());
                                paramArray = "@" + string.Join(",@", columnList.ToArray());

                                string[] pkColums = sourceEntity.FileNodes.Where(o => o.IsPrimaryKey).Select(p => p.Name).ToArray();

                                @where = pkColums.Aggregate(@where, (current, pk) => current + ("and " + pk + "=@" + pk + " "));
                                if (@where.Length > 3)
                                {
                                    @where = @where.Remove(0, 3);
                                }
                                set = columnList.Where(c => !pkColums.Contains(c)).Aggregate(set, (current, c) => current + ("," + c + "=@" + c + " "));
                                if (set.Length > 1)
                                {
                                    set = set.Remove(0, 1);
                                }
                            }
                   
                            string selectSql = string.Format("select count(*) from [{0}] where {1}",
                                                             sourceEntity.Name,
                                                             @where);
                            int count = (int)DBOperatorFactory.GetOperator.ExecScalar(selectSql, DataConnection, paramlist, TransactionType.Transaction);
                            if (count > 0)
                            {
                            
                                //更新
                                string updateSql = string.Format("update [{0}] set {1} where {2}",
                                                                 sourceEntity.Name,
                                                                 set,
                                                                 @where);
                                DBOperatorFactory.GetOperator.ExecSql(updateSql, DataConnection, paramlist, TransactionType.Transaction);
                            }
                            else
                            {
                                string insertsql = string.Format("insert into [{0}]({1}) values({2})", targetEntity.Name, columnArray, paramArray);
                                DBOperatorFactory.GetOperator.ExecSql(insertsql, DataConnection, paramlist, TransactionType.Transaction);
                            }
                        }
                    }
                    if (showmessag())   //MessageBox.Show("确定是否提交？", "提示", MessageBoxButton.OKCancel) == MessageBoxResult.OK)
                    {
                        DBOperatorFactory.GetOperator.CommitTransaction(DataConnection);
                    }
                    else
                    {
                        DBOperatorFactory.GetOperator.RollbackTransaction(DataConnection);
                    }
                }
                catch (Exception ex)
                {
                    DBOperatorFactory.GetOperator.RollbackTransaction(DataConnection);
                    MessageBox.Show("数据已回滚.详细:"+ex.Message);
                }
            }
        }

        private object GetStrateGy(string fieldName,Dictionary<string,string> dic,object newValue)
        {
            if (dic == null)
                return newValue;
            if (dic.ContainsKey(fieldName))
            {
                switch (dic[fieldName])
                {
                    case "[GUID]":
                        return Guid.NewGuid().ToString();
                    case "[DATE]":
                        return DateTime.Now;
                    case "[原始值]":
                        return null;
                    case "[目标值]":
                        return newValue;
                    default:
                        return dic[fieldName];
                }
            }
            return newValue;
        }

        public void Exec(Action action, string description)
        {
            IsBusy = true;
            Action act = () =>
            {
                WriteLog(description + "开始……", Colors.Blue);
                action();
                WriteLog(description + "结束……", Colors.Blue);
            };
            if (DataSource != null && TargetSource != null)
            {
                if (DataSource.Count != DataSourceList.Count || TargetSource.Count != TargetSourceList.Count)
                {
                    WriteLog("数据不匹配，正在重新加载数据……", Colors.Blue);
                    Refresh(act);
                    return;
                }
            }

            Task.Factory.FromAsync(act.BeginInvoke, act.EndInvoke, null)
                .ContinueWith(t => {
                    IsBusy = false;
                });
        }
        public void WriteLog(string msg, Color isError)
        {
            if (AppendLogAction != null)
            {
                AppendLogAction(msg, isError);
            }
        }



        public Action<Action> ViewInvoke { get; set; }
        public Action<string, Color> AppendLogAction
        {
            private get;
            set;
        }
        public bool IsBusy { get; set; }
    }




    public class DBComparsionEntity : BasePropertyChange
    {
        public DBComparsionEntity()
        {
            FontColor = Brushes.Black;
        }
        private string _name;
        private Brush _brush;
        public string Name
        {
            get { return _name; }
            set
            {
                if (value != _name)
                {
                    _name = value;
                    this.NotifyPropertyChanged(o => o.Name);
                }
            }
        }
        private string _description;
        public string Description
        {
            get { return _description; }
            set
            {
                if (value != _description)
                {
                    _description = value;
                    this.NotifyPropertyChanged(o => o.Description);
                }
            }
        }
        public Brush FontColor
        {
            get { return _brush; }
            set
            {
                if (!Equals(value, _brush))
                {
                    _brush = value;
                    this.NotifyPropertyChanged(o => o.FontColor);
                }
            }
        }
        private bool _isSelected;
        /// <summary>
        /// 是否选中
        /// </summary>
        public bool IsSelected
        {
            get { return _isSelected; }
            set
            {
                if (value != _isSelected)
                {
                    this._isSelected = value;
                    this.NotifyPropertyChanged(o => o.IsSelected);
                }
            }
        }

        private string _sqlContent;
        public string SqlContent
        {
            get { return _sqlContent; }
            set
            {
                if (value != _sqlContent)
                {
                    _sqlContent = value;
                    this.NotifyPropertyChanged(o => o.SqlContent);
                }
            }
        }
        public ObservableCollection<DBComparsionEntity> Childs { get; set; }
    }
    public enum ComparisonType
    {
        相等,
        不等于,
        缺失
    }
    public class TableComparisonEntity
    {
        public TableComparisonEntity()
        {
            IsUpdate = true;
        }
        public string TableName { get; set; }
        public ComparisonType TableStatus { get; set; }
        public bool IsUpdate { get; set; }
        public int UpdateCount { get; set; }
        public string UpdateContent { get; set; }
    }
    public class ColumnComparisonEntity
    {
        public ColumnComparisonEntity()
        {
            IsUpdate = true;
        }
        public bool IsUpdate { get; set; }
        public string TableName { get; set; }
        public string ColumnName { get; set; }
        public string DataType { get; set; }
        public string IsNullable { get; set; }
        public string Length { get; set; }
        public bool IsPrimaryKey { get; set; }
        public string SourceType { get; set; }
        public string UpdateContent { get; set; }
        public ColumnComparisonInfo ComparisionInfo { get; set; }
        public ComparisonType Status { get; set; }
    }

    [Flags]
    public enum ColumnComparisonInfo
    {
        默认 = 1,
        数据类型不相等 = 2,
        可空类型不相等 = 4,
        长度不相等 = 8,
        主键不相等 = 16
    }
}
